/*
 *
 *      Copyright (c) 2018-2025, st All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the pig4cloud.com developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: st
 *
 */

package com.mkh.st.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codingapi.tx.annotation.TxTransaction;
import com.mkh.st.admin.api.dto.*;
import com.mkh.st.admin.api.entity.*;
import com.mkh.st.admin.api.vo.*;
import com.mkh.st.admin.mapper.*;
import com.mkh.st.admin.service.*;
import com.mkh.st.admin.strategy.Context;
import com.mkh.st.common.core.constant.CommonConstants;
import com.mkh.st.common.core.constant.enums.*;
import com.mkh.st.common.core.exception.BizException;
import com.mkh.st.common.core.util.R;
import com.mkh.st.common.security.service.DaoismUser;
import com.mkh.st.common.security.util.SecurityUtils;
import com.mkh.st.purchase.api.feign.IPurchaseGroupProvider;
import com.mkh.st.purchase.api.feign.ISupplierProvider;
import com.mkh.st.purchase.dto.DataPermissionDTO;
import com.mkh.st.purchase.vo.PurchaseGroupVO;
import com.mkh.st.purchase.vo.SupplierVO;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author st
 * @date 2017/10/31
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

	private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

	private final SysMenuService sysMenuService;

	private final SysUserMapper sysUserMapper;

	private final SysUserRoleService sysUserRoleService;

	private final SysRoleMenuService sysRoleMenuService;

	private final SysUserRoleScopeService sysUserRoleScopeService;

	private final SysRoleMapper sysRoleMapper;

	private final SysPermissionScopeService sysPermissionScopeService;

	private final SysMenuMapper sysMenuMapper;

	private final SysTenantMapper sysTenantMapper;

	private final Context context;

	private final SysDocTypeMapper sysDocTypeMapper;

	private  final IPurchaseGroupProvider purchaseGroupProvider;

	private final ISupplierProvider supplierProvider;

	private final List<Long> userScopeIds= Arrays.asList(ScopeEnum.USER.getId());

	private final List<Long> purchaseScopeIds= Arrays.asList(ScopeEnum.PURCHASE.getId());

	private final List<Long> supplierScopeIds= Arrays.asList(ScopeEnum.SUPPLIER.getId());



	@Override
	public R<IPage<UserPageVO>> getUserPage(Page page, UserPageDTO dto) {
		DataPermissionVO dataPermissionVO=getDataPermisston(CommonConstants.ZERO,MenuEnum.SYSTEM_ACCOUNTNUMBER.getCode(),userScopeIds);
		IPage<SysUser> iPage = sysUserMapper.selectPage(page,Wrappers.<SysUser>lambdaQuery()
			.eq(SysUser::getDelFlag,CommonConstants.NOT_DEL).eq(SysUser::getTenantId, SecurityUtils.getUser().getTenantId())
			.eq(SysUser::getUserType, UserTypeEnum.TENANT_USER.getCode())
			.in(CollectionUtil.isNotEmpty(dto.getNormalFlag()),SysUser::getNormalFlag,dto.getNormalFlag())
			.in(BooleanUtil.isFalse(dataPermissionVO.getUserAll()),SysUser::getUserId,dataPermissionVO.getUserList())
			.like(StrUtil.isNotBlank(dto.getPhone()),SysUser::getPhone,dto.getPhone())
			.like(StrUtil.isNotBlank(dto.getUsername()),SysUser::getUsername,dto.getUsername()).orderByDesc(SysUser::getUserId));
		IPage<UserPageVO> iPageInfo=new Page<>();
		if(CollectionUtil.isEmpty(iPage.getRecords())){
			return R.ok(iPageInfo);
		}
		List<UserPageVO> list=new ArrayList<>();
		iPage.getRecords().forEach(item ->{
			UserPageVO vo=BeanUtil.toBean(item,UserPageVO.class);
			vo.setNormalFlagName(UserStatusEnum.get(item.getNormalFlag()).getValue());
			vo.setSexName(SexEnum.get(item.getSex()).getValue());
			list.add(vo);
		});
		iPageInfo.setRecords(list).setTotal(iPage.getTotal()).setSize(iPage.getSize()).setCurrent(iPage.getCurrent()).setPages(iPage.getPages());
		return R.ok(iPageInfo);
	}

	@Override
	public List<UserPageVO> getUserList(UserPageDTO dto) {
		DataPermissionVO dataPermissionVO=getDataPermisston(CommonConstants.ZERO,MenuEnum.SYSTEM_ACCOUNTNUMBER.getCode(),userScopeIds);
		List<SysUser> userList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getUserType, UserTypeEnum.TENANT_USER.getCode())
				.eq(SysUser::getDelFlag,CommonConstants.NOT_DEL).eq(SysUser::getTenantId, SecurityUtils.getUser().getTenantId())
				.in(CollectionUtil.isNotEmpty(dto.getNormalFlag()),SysUser::getNormalFlag,dto.getNormalFlag())
				.in(BooleanUtil.isFalse(dataPermissionVO.getUserAll()),SysUser::getUserId,dataPermissionVO.getUserList())
				.like(StrUtil.isNotBlank(dto.getPhone()),SysUser::getPhone,dto.getPhone())
				.like(StrUtil.isNotBlank(dto.getUsername()),SysUser::getUsername,dto.getUsername()).orderByDesc(SysUser::getUserId));
		List<UserPageVO> list=userList.stream().map(v ->BeanUtil.toBean(v,UserPageVO.class)).collect(Collectors.toList());
		return list;
	}

    @Override
    public List<UserIdNameVO> getUserNameList(String ids) {
		List<Long> userIds= Convert.toList(Long.class, StrUtil.split(ids,','));
		List<SysUser> userList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
			.in(SysUser::getUserId,userIds));
		List<UserIdNameVO> list=userList.stream().map(v ->BeanUtil.toBean(v,UserIdNameVO.class)).collect(Collectors.toList());
		return list;
    }

	@Override
	public List<UserIdNameVO> getSaleUserList(Integer businessType) {
		List<SysUser> userList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getUserType, UserTypeEnum.TENANT_USER.getCode())
				.eq(SysUser::getDelFlag,CommonConstants.NOT_DEL).eq(SysUser::getTenantId, SecurityUtils.getUser().getTenantId())
				.eq(SysUser::getNormalFlag,UserStatusEnum.NORMAL.getStatus()).eq(SysUser::getUserBusinessType,businessType));
		if(CollectionUtil.isNotEmpty(userList)){
			List<UserIdNameVO> list=userList.stream().map(v ->BeanUtil.toBean(v,UserIdNameVO.class)).collect(Collectors.toList());
			return  list;
		}
		return null;
	}

    @Override
    public List<UserIdNameVO> getPurchaseUserList(String keyWord) {
		DataPermissionVO dataPermissionVO=getDataPermisston(CommonConstants.ONE,MenuEnum.SELL_INDENT.getCode(),userScopeIds);
		List<SysUser> userList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getDelFlag,CommonConstants.NOT_DEL).eq(SysUser::getTenantId, SecurityUtils.getUser().getTenantId())
				.eq(SysUser::getUserType, UserTypeEnum.TENANT_USER.getCode())
				.eq(SysUser::getUserBusinessType,UserBusinessTypeEnum.SUPPLY.getCode())
				.in(!dataPermissionVO.getUserAll(),SysUser::getUserId,dataPermissionVO.getUserList())
				.like(StrUtil.isNotBlank(keyWord),SysUser::getUsername,keyWord)
				.orderByDesc(SysUser::getUserId));
		if(CollectionUtil.isNotEmpty(userList)){
			List<UserIdNameVO> list=userList.stream().map(v ->BeanUtil.toBean(v,UserIdNameVO.class)).collect(Collectors.toList());
			return list;
		}else {
			List<UserIdNameVO> list =new ArrayList<>();
			UserIdNameVO vo=new UserIdNameVO();
			vo.setUserId(2L);
			vo.setUsername("我是采购员");
			list.add(vo);
			return list;
		}

    }

	@Override
	public List<UserIdNameVO> getUsersList(String keyWord, Integer userType, String menuCode) {
		DataPermissionVO dataPermissionVO=getDataPermisston(CommonConstants.ONE,menuCode,userScopeIds);
		List<SysUser> userList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getDelFlag,CommonConstants.NOT_DEL).eq(SysUser::getTenantId, SecurityUtils.getUser().getTenantId())
				.eq(SysUser::getUserType, UserTypeEnum.TENANT_USER.getCode())
				.eq(SysUser::getUserBusinessType,userType)
				.in(!dataPermissionVO.getUserAll(),SysUser::getUserId,dataPermissionVO.getUserList())
				.like(StrUtil.isNotBlank(keyWord),SysUser::getUsername,keyWord)
				.orderByDesc(SysUser::getUserId));
		if(CollectionUtil.isNotEmpty(userList)){
			List<UserIdNameVO> list=userList.stream().map(v ->BeanUtil.toBean(v,UserIdNameVO.class)).collect(Collectors.toList());
			return list;
		}
		return null;
	}

	@Override
	public List<PurchaseGroupVO> getPurchaseGroupList(String menuCode,Long siteId) {
		DataPermissionVO dataPermissionVO=getDataPermisston(CommonConstants.ONE,menuCode,purchaseScopeIds);
		DataPermissionDTO dto=new DataPermissionDTO();
		if(ObjectUtil.isNotNull(siteId)){
			dto.setSiteId(siteId);
		}
		dto.setAllFlag(dataPermissionVO.getPurchaseAll());
		dto.setIds(dataPermissionVO.getPurchaseList());
		dto.setTenantId(SecurityUtils.getUser().getTenantId());
		List<PurchaseGroupVO> list = purchaseGroupProvider.getDataPermPurchaseGroup(dto).getData();
		return list;
	}

	@Override
	public List<SupplierVO> getSupplierList(String menuCode) {
		DataPermissionVO dataPermissionVO=getDataPermisston(CommonConstants.ONE,menuCode,supplierScopeIds);
		DataPermissionDTO dto=new DataPermissionDTO();
		dto.setAllFlag(dataPermissionVO.getSupplierAll());
		dto.setIds(dataPermissionVO.getSupplierList());
		dto.setTenantId(SecurityUtils.getUser().getTenantId());
		List<SupplierVO> list = supplierProvider.getDataPermSuppliers(dto).getData();
		return list;
	}

    @Override
    public List<UserIdNameVO> getAllUsersList(String keyWord, String menuCode) {
		DataPermissionVO dataPermissionVO=getDataPermisston(CommonConstants.ONE,menuCode,userScopeIds);
		List<SysUser> userList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getDelFlag,CommonConstants.NOT_DEL).eq(SysUser::getTenantId, SecurityUtils.getUser().getTenantId())
				.eq(SysUser::getUserType, UserTypeEnum.TENANT_USER.getCode())
				.eq(SysUser::getNormalFlag,CommonConstants.ZERO)
				.in(!dataPermissionVO.getUserAll(),SysUser::getUserId,dataPermissionVO.getUserList())
				.like(StrUtil.isNotBlank(keyWord),SysUser::getUsername,keyWord)
				.orderByDesc(SysUser::getUserId));
		if(CollectionUtil.isNotEmpty(userList)){
			List<UserIdNameVO> list=userList.stream().map(v ->BeanUtil.toBean(v,UserIdNameVO.class)).collect(Collectors.toList());
			return list;
		}
		return null;
    }


	@Override
	public R<UserDetailVO> getUserDetail(Long userId) {
		SysUser sysUser=sysUserMapper.selectById(userId);
		UserDetailVO vo=BeanUtil.toBean(sysUser,UserDetailVO.class);
		//查询用户已分配的角色
		List<SysUserRole> roleList=sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId,userId));
		if(CollectionUtil.isNotEmpty(roleList)){
			List<RoleIdListVO> list=new ArrayList<>();
			roleList.forEach(item ->{
				SysRole sysRole=sysRoleMapper.selectOne(Wrappers.<SysRole>lambdaQuery()
					.eq(SysRole::getDelFlag,CommonConstants.NOT_DEL).eq(SysRole::getRoleId,item.getRoleId()));
				if(ObjectUtil.isNotNull(sysRole)){
					RoleIdListVO vo1=new RoleIdListVO();
					vo1.setId(sysRole.getRoleId());
					vo1.setRoleName(sysRole.getRoleName());
					list.add(vo1);
				}
			});
			vo.setRoleList(list);
		}
		return R.ok(vo);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveUserInfo(UserSaveDTO dto) {
		SysUser sysUser=BeanUtil.toBean(dto,SysUser.class);
		DaoismUser user = SecurityUtils.getUser();
		if(ObjectUtil.isNotNull(dto.getUserId())){
			sysUser.setUpdateBy(user.getName()).setUpdateId(user.getId()).setUpdateTime(LocalDateTime.now());
			if(!updateById(sysUser)){
				throw new BizException(ResultCodeEnum.USER_UPDATE_FAIL);
			}
			List<SysUser> list=list(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getPhone,dto.getPhone()).eq(SysUser::getDelFlag,CommonConstants.NOT_DEL)
				.ne(SysUser::getUserId,dto.getUserId()));
			if(CollectionUtil.isNotEmpty(list)){
				throw new BizException(100,"手机号码已存在!");
			}
			//删除用户角色关联信息
			sysUserRoleService.remove(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId,dto.getUserId()));
		}else {
			//查询租户最大用户数
			SysTenant sysTenant = sysTenantMapper.selectById(user.getTenantId());
			Integer count = sysUserMapper.selectCount(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getTenantId, user.getTenantId()));
			if(count.compareTo(sysTenant.getMaxUserCount())!=-1){
				throw new BizException(ResultCodeEnum.USER_MAX_COUNT);
			}
			List<SysUser> list=list(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getPhone,dto.getPhone()).eq(SysUser::getDelFlag,CommonConstants.NOT_DEL));
			if(CollectionUtil.isNotEmpty(list)){
				throw new BizException(100,"手机号码已存在!");
			}
			sysUser.setTenantId(user.getTenantId()).setCreateTime(LocalDateTime.now())
					.setCreateId(user.getId()).setCreateBy(user.getName()).setNotShow(CommonConstants.NOT_DEL)
					.setPassword(ENCODER.encode(CommonConstants.DEFAULT_PASSWORD));
			if(!save(sysUser)){
				throw new BizException(ResultCodeEnum.USER_ADD_FAIL);
			}
		}

		if(CollectionUtil.isNotEmpty(dto.getRoleList())){
			List<SysUserRole> sysUserRoleList=new ArrayList<>();
			dto.getRoleList().forEach(item ->{
				SysUserRole sysUserRole=new SysUserRole(sysUser.getUserId(),item.getId());
				sysUserRoleList.add(sysUserRole);
			});
			if(!sysUserRoleService.saveBatch(sysUserRoleList)){
				throw new BizException(ResultCodeEnum.USER_ADD_ROLE_FAIL);
			}
			//新增时赋予当前操作人的数据权限
			if(ObjectUtil.isNull(dto.getUserId())){
				List<Long> roles = SecurityUtils.getRoles();
				//查询哪个角色有账户设置的权限
				SysMenu sysMenu=sysMenuService.getOne(Wrappers.<SysMenu>lambdaQuery().eq(SysMenu::getPermission, MenuEnum.SYSTEM_ACCOUNTNUMBER.getCode()));
				AtomicReference<Long> roleId= new AtomicReference<Long>((long) 0);
				List<Long> haveRoles=new ArrayList<>();
				roles.forEach(item ->{
					SysRoleMenu sysRoleMenu=sysRoleMenuService.getOne(Wrappers.<SysRoleMenu>lambdaQuery()
							.eq(SysRoleMenu::getRoleId,item).eq(SysRoleMenu::getMenuId,sysMenu.getMenuId()));
					if(ObjectUtil.isNotNull(sysRoleMenu)){
						roleId.set(item);
						haveRoles.add(item);
					}
				});
				List<SysUserRoleScope> list = sysUserRoleScopeService.list(Wrappers.<SysUserRoleScope>lambdaQuery()
						.eq(SysUserRoleScope::getRoleId,roleId.get()).eq(SysUserRoleScope::getUserId,user.getId()));
				if(CollectionUtil.isNotEmpty(list)){
					List<SysUserRoleScope> addList=new ArrayList<>();
					list.forEach(ie ->{
						for(RoleIdListVO roleListVO : dto.getRoleList()){
							SysUserRoleScope scope=BeanUtil.toBean(ie,SysUserRoleScope.class);
							scope.setId(null).setUserId(sysUser.getUserId()).setRoleId(roleListVO.getId());
							addList.add(scope);
						}
					});
					if(!sysUserRoleScopeService.saveBatch(addList)){
						throw new BizException(ResultCodeEnum.USER_ADD_DATA_SCOPE_FAIL);
					}
				}
				//新增的用户加入数据权限
				haveRoles.forEach(haveId ->{
					SysUserRoleScope scope = sysUserRoleScopeService.getOne(Wrappers.<SysUserRoleScope>lambdaQuery()
						.eq(SysUserRoleScope::getRoleId,haveId).eq(SysUserRoleScope::getUserId,user.getId())
						.eq(SysUserRoleScope::getScopeId,ScopeEnum.USER.getId()));
					if(CommonConstants.ZERO== scope.getAllFlag()){
						scope.setIds(scope.getIds()+","+sysUser.getUserId());
						if(!sysUserRoleScopeService.updateById(scope)){
							throw new BizException(ResultCodeEnum.USER_ADD_FAIL);
						}
					}
				});
			}
		}
		return Boolean.TRUE;
	}

	@Override
	public Boolean updateUserPassword(UserPasswordDTO dto) {

		if(!dto.getNewPassword().equals(dto.getComfirmPassword())){
			throw new BizException(ResultCodeEnum.USER_NEW_OLD_PASSWORD_DIFF);
		}
		if(dto.getType()==CommonConstants.ZERO){//后台重置
			DaoismUser user = SecurityUtils.getUser();
			SysUser sysUser=new SysUser();
			sysUser.setUserId(dto.getUserId()).setPassword(ENCODER.encode(dto.getNewPassword()))
					.setUpdateId(user.getId()).setUpdateBy(user.getName()).setUpdateTime(LocalDateTime.now());
			if(!updateById(sysUser)){
				throw new BizException(ResultCodeEnum.USER_UPDATE_PASSWORD_FAIL);
			}
		}else {//自己修改
			SysUser exist = sysUserMapper.selectById(dto.getUserId());
			if (!ENCODER.matches(dto.getOldPassword(),exist.getPassword())) {
				throw new BizException(ResultCodeEnum.USER_PASSWORD_DIFF);
			}
			exist.setPassword(ENCODER.encode(dto.getNewPassword()));
			if(!updateById(exist)){
				throw new BizException(ResultCodeEnum.USER_UPDATE_PASSWORD_FAIL);
			}
		}
		return Boolean.TRUE;
	}

    @Override
	@Transactional(rollbackFor = Exception.class)
    public Boolean copyUserDataScope(UserCopyDataScopeDTO dto) {
		for (Long id : dto.getUserIds()) {
			if(id.equals(dto.getUserIdCopyed())){
				continue;
			}
			//查询需要复制的用户的角色
			List<Long> roleIdlist =sysRoleMapper.getRoleIdsByUserId(id);
			//查询被复制的用户的角色
			List<Long> roleIdCopelist =sysRoleMapper.getRoleIdsByUserId(dto.getUserIdCopyed());
			if(CollectionUtil.isEmpty(roleIdlist) || CollectionUtil.isEmpty(roleIdCopelist)){
				throw new BizException(ResultCodeEnum.USER_ROLE_DIFF);
			}
			roleIdlist.forEach(item ->{
				if(roleIdCopelist.stream().filter(v ->v.equals(item)).findFirst().isPresent()){
					/**存在相同角色时复制数据权限**/
					List<SysPermissionScope> permissionScopeList = sysPermissionScopeService.list(Wrappers.<SysPermissionScope>lambdaQuery()
							.eq(SysPermissionScope::getScopeType,dto.getType()));
					//集团级or站点级维度查询
					List<Long> scopeIds=permissionScopeList.stream().map(SysPermissionScope::getScopeId).collect(Collectors.toList());
					//被copy用户角色的数据权限
					List<SysUserRoleScope> dataSopeList = sysUserRoleScopeService.list(Wrappers.<SysUserRoleScope>lambdaQuery()
							.eq(SysUserRoleScope::getUserId,dto.getUserIdCopyed()).eq(SysUserRoleScope::getRoleId,item)
							.in(SysUserRoleScope::getScopeId,scopeIds));
					//删除需要copy的用户角色原有的数据权限
					sysUserRoleScopeService.remove(Wrappers.<SysUserRoleScope>lambdaQuery()
							.eq(SysUserRoleScope::getUserId,id).eq(SysUserRoleScope::getRoleId,item)
							.in(SysUserRoleScope::getScopeId,scopeIds));
					//复制数据权限
					dataSopeList.forEach(entity ->{
						entity.setId(null).setUserId(id);
					});
					if(!sysUserRoleScopeService.saveBatch(dataSopeList)){
						throw new BizException(ResultCodeEnum.USER_DATA_COPY_FAIL);
					}
				}
			});
		}
		return Boolean.TRUE;
    }

	@Override
	public List<UserRoleScopeListVO> getUserRoleScopeList(UserRoleScopeDTO dto) {
		List<UserRoleScopeListVO> list=new ArrayList<>();
		List<Long> roleIdlist =sysRoleMapper.getRoleIdsByUserId(dto.getUserId());
		if(CollectionUtil.isEmpty(roleIdlist)){
			return 	list;
		}
		List<SysRole> roleList=sysRoleMapper.selectBatchIds(roleIdlist);
		List<SysPermissionScope> scopes = sysPermissionScopeService.list(Wrappers.<SysPermissionScope>lambdaQuery()
			.eq(SysPermissionScope::getScopeType,dto.getType()));
		List<ScopeListVO> scopeList=scopes.stream().map(v -> BeanUtil.toBean(v,ScopeListVO.class)).collect(Collectors.toList());
		roleList.forEach(item ->{
			UserRoleScopeListVO vo=BeanUtil.toBean(item,UserRoleScopeListVO.class);
			vo.setScopeList(scopeList);
			list.add(vo);
		});
		return list;
	}

	@Override
	public List<ScopeDataDeatil> getUserScopeDataList(UserRoleDataDTO dto) {
		//要取数据库数据
		DataPermissionVO dataPermissionVO=getDataPermisston(CommonConstants.ZERO,MenuEnum.SYSTEM_ACCOUNTNUMBER.getCode(),dto.getScopeIds());
		//选择的账号数据权限
		List<ScopeDataDeatil> list=new ArrayList<>();
		dto.getScopeIds().forEach(item ->{
			SysUserRoleScope one = sysUserRoleScopeService.getOne(Wrappers.<SysUserRoleScope>lambdaQuery()
					.eq(SysUserRoleScope::getUserId,dto.getUserId()).eq(SysUserRoleScope::getRoleId,dto.getRoleId())
					.eq(SysUserRoleScope::getScopeId,item));
			ScopeDataDeatil vo=context.getScopeStrategy(item).getScopeDataList(dataPermissionVO,one,item);
			if(ObjectUtil.isNotNull(one)){
				if(one.getAllFlag()==CommonConstants.ONE){
					vo.setUserAllFlag(Boolean.TRUE);
				}
			}
			list.add(vo);
		});
		return list;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean userScopeDataSave(UserRoleDataSaveDTO dto) {
		dto.getList().forEach( item ->{
			SysUserRoleScope scope=sysUserRoleScopeService.getOne(Wrappers.<SysUserRoleScope>lambdaQuery()
				.eq(SysUserRoleScope::getScopeId,item.getScopeId()).eq(SysUserRoleScope::getRoleId,dto.getRoleId())
				.eq(SysUserRoleScope::getUserId,dto.getUserId()));
			List<Long> checkedIds=new ArrayList<>();
			List<Long> notCheckedIds=new ArrayList<>();
			if(CollectionUtil.isNotEmpty(item.getIds())){
				//已选中
				checkedIds=item.getIds().stream().filter( v -> v.getChecked()).map(IdCheckDTO::getId).collect(Collectors.toList());
				//					未选中 1 3
				notCheckedIds=item.getIds().stream().filter( v -> !v.getChecked()).map(IdCheckDTO::getId).collect(Collectors.toList());
			}
			if(ObjectUtil.isNotNull(scope)){
				List<Long> finalNotCheckedIds = notCheckedIds;
				if(!item.getAllFlag()){//不是保存全部数据权限时
					if(scope.getAllFlag()==CommonConstants.ZERO){//账号没有全部权限
						if(StrUtil.isNotBlank(scope.getIds())){//没有数据权限数据
							List<Long> userList = Convert.toList(Long.class, StrUtil.split(scope.getIds(),','));
							userList = userList.stream().filter(t-> !finalNotCheckedIds.contains(t)).collect(Collectors.toList());
							userList = Stream.of(userList,checkedIds).flatMap(Collection::stream).distinct().collect(Collectors.toList());
							scope.setIds(CollectionUtil.join(userList,","));
						}else {
							scope.setIds(CollectionUtil.join(checkedIds,","));
						}
					}else {//账号有全部权限
					 	List<Long> list=context.getScopeStrategy(item.getScopeId()).getList(SecurityUtils.getUser().getTenantId());
					 	if(CollectionUtil.isNotEmpty(list)){
							list = list.stream().filter(t-> !finalNotCheckedIds.contains(t)).collect(Collectors.toList());
							list = Stream.of(list,checkedIds).flatMap(Collection::stream).distinct().collect(Collectors.toList());
							scope.setIds(CollectionUtil.join(list,","));
					 	}else {
					 		scope.setIds(CollectionUtil.join(checkedIds,","));
					 	}
					}
					scope.setAllFlag(CommonConstants.ZERO);
				}else {
					scope.setAllFlag(CommonConstants.ONE);
				}
				if(!sysUserRoleScopeService.updateById(scope)){
					throw new BizException(ResultCodeEnum.USER_DATA_SAVE_FAIL);
				}
			}else {//没有被设置过数据权限
				SysUserRoleScope entity=new SysUserRoleScope();
				entity.setUserId(dto.getUserId()).setRoleId(dto.getRoleId()).setScopeId(item.getScopeId());
				if(!item.getAllFlag() && CollectionUtil.isNotEmpty(item.getIds())){
					entity.setIds(CollectionUtil.join(checkedIds,","));
				}else{
					entity.setIds("");
				}
				if(item.getAllFlag()){
					entity.setAllFlag(CommonConstants.ONE);
				}else {
					entity.setAllFlag(CommonConstants.ZERO);
				}
				if(!sysUserRoleScopeService.save(entity)){
					throw new BizException(ResultCodeEnum.USER_DATA_SAVE_FAIL);
				}
			}
		});
		return Boolean.TRUE;
	}


	//数据权限合并 type=0实时权限，1缓存权限
	@Override
	public DataPermissionVO getDataPermisston(Integer type, String menuCode, List<Long> scopeIds) {
		List<DataPermissionVO> dataScopes=new ArrayList<>();
		if(type==CommonConstants.ZERO){
			DaoismUser user = SecurityUtils.getUser();
			dataScopes =sysUserRoleScopeService.getPermissionListByScopeIds(user.getId(),user.getTenantId(),SecurityUtils.getRoles(),scopeIds);
		}else if(type==CommonConstants.ONE){
			dataScopes=	SecurityUtils.getUser().getDataScopes();
		}
		//只有一个角色时直接返回
		if(dataScopes.size()==1){
			return dataScopes.get(0);
		}
		SysMenu sysMenu=sysMenuService.getOne(Wrappers.<SysMenu>lambdaQuery().eq(SysMenu::getPermission, menuCode));
		DataPermissionVO vo=new DataPermissionVO();
		dataScopes.forEach(item ->{
			SysRoleMenu sysRoleMenu=sysRoleMenuService.getOne(Wrappers.<SysRoleMenu>lambdaQuery()
				.eq(SysRoleMenu::getRoleId,item.getRoleId()).eq(SysRoleMenu::getMenuId,sysMenu.getMenuId()));
			if(ObjectUtil.isNotNull(sysRoleMenu)){
				for (Long scopeId: scopeIds) {
					context.getScopeStrategy(scopeId).getUserDataPermission(vo,item);
				}
			}
		});
		return vo;
	}

	@Override
	public DataPermissionVO getUserDataPermisstion(String docTypeCode, String menuCode) {
		if(StrUtil.isNotBlank(docTypeCode)){
			SysDocType sysDocType = sysDocTypeMapper.selectOne(Wrappers.<SysDocType>lambdaQuery().eq(SysDocType::getCode,docTypeCode));
			List<Long> ids = Convert.toList(Long.class, StrUtil.split(sysDocType.getScopeIds(), ','));
			return getDataPermisston(CommonConstants.ONE,menuCode,ids);
		}
		List<SysPermissionScope> list = sysPermissionScopeService.list();
		List<Long> ids=list.stream().map(SysPermissionScope::getScopeId).collect(Collectors.toList());
		return getDataPermisston(CommonConstants.ONE,menuCode,ids);
	}

	@Override
	public Page<UserPurchasePageVO> purchaseUserPage( UserPurchasePageDTO dto) {
		Page page = new Page(dto.getCurrent(),dto.getSize());
		IPage<SysUser> iPage = sysUserMapper.selectPage(page,Wrappers.<SysUser>lambdaQuery()
			.eq(SysUser::getDelFlag,CommonConstants.NOT_DEL).eq(SysUser::getTenantId, SecurityUtils.getUser().getTenantId())
			.eq(SysUser::getUserType, UserTypeEnum.TENANT_USER.getCode())
			.eq(SysUser::getUserBusinessType,UserBusinessTypeEnum.SUPPLY.getCode())
			.in(BooleanUtil.isFalse(dto.getAllFlag()),SysUser::getUserId,dto.getUserList())
			.and(StrUtil.isNotBlank(dto.getKeyWords()),wrapper -> wrapper.like(SysUser::getPhone,dto.getKeyWords())
				.or().like(SysUser::getUsername,dto.getKeyWords()))
			.orderByDesc(SysUser::getUserId));
		Page<UserPurchasePageVO> iPageInfo=new Page<>();
		if(CollectionUtil.isEmpty(iPage.getRecords())){
			return iPageInfo;
		}
		List<UserPurchasePageVO> list=iPage.getRecords().stream().map(v ->BeanUtil.toBean(v,UserPurchasePageVO.class)).collect(Collectors.toList());
		iPageInfo.setRecords(list).setTotal(iPage.getTotal()).setSize(iPage.getSize()).setCurrent(iPage.getCurrent()).setPages(iPage.getPages());
		return iPageInfo;
	}

	@Override
	public List<UserPurchasePageVO> purchaseUserList(UserPurchasePageDTO dto) {
		List<SysUser> userList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getDelFlag,CommonConstants.NOT_DEL).eq(SysUser::getTenantId, SecurityUtils.getUser().getTenantId())
				.eq(SysUser::getUserType, UserTypeEnum.TENANT_USER.getCode())
				.eq(SysUser::getUserBusinessType,UserBusinessTypeEnum.SUPPLY.getCode())
				.in(BooleanUtil.isFalse(dto.getAllFlag()),SysUser::getUserId,dto.getUserList())
				.like(StrUtil.isNotBlank(dto.getKeyWords()),SysUser::getUsername,dto.getKeyWords())
				.orderByDesc(SysUser::getUserId));
		List<UserPurchasePageVO> list=userList.stream().map(v ->BeanUtil.toBean(v,UserPurchasePageVO.class)).collect(Collectors.toList());
		return  list;
	}

	/**
	 * 客户信息保存
	 * @param dto
	 * @return
	 */
	@Override
	@TxTransaction
	@Transactional(rollbackFor = Exception.class)
	public Long otherUserSave(OtherUserDTO dto) {
		DaoismUser user = SecurityUtils.getUser();
		SysUser entity=BeanUtil.toBean(dto,SysUser.class);
		if(ObjectUtil.isNotNull(dto.getUserId())){
			Integer integer = sysUserMapper.selectCount(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, dto.getPhone())
					.eq(SysUser::getDelFlag, CommonConstants.NOT_DEL).ne(SysUser::getUserId,dto.getUserId()));
			if(integer!=CommonConstants.ZERO){
				throw new BizException(1001,"用户账号已存在!");
			}
			if(StrUtil.isNotBlank(dto.getPassword())) {
				entity.setPassword(ENCODER.encode(dto.getPassword()));
			}
			entity.setUpdateTime(LocalDateTime.now()).setUpdateBy(user.getName()).setUpdateId(user.getId());
			if(!updateById(entity)){
				throw new BizException(ResultCodeEnum.USER_ADD_FAIL);
			}
		}else {
			Integer integer = sysUserMapper.selectCount(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, dto.getPhone())
					.eq(SysUser::getDelFlag, CommonConstants.NOT_DEL));
			if(integer!=CommonConstants.ZERO){
				throw new BizException(1002,"用户账号已存在!");
			}
			entity.setBeginTime(LocalDateTime.now()).setEndTime(LocalDateTime.of(2099,12,31,23,59,59))
					.setCreateBy(user.getName()).setCreateTime(LocalDateTime.now()).setCreateId(user.getId()).setTenantId(user.getTenantId())
					.setPassword(ENCODER.encode(dto.getPassword()));
			if(!save(entity)){
				throw new BizException(ResultCodeEnum.USER_UPDATE_FAIL);
			}
		}
		return entity.getUserId();
	}

	@Override
	public Boolean deleteUser(DeleteDto dto) {
		LambdaUpdateWrapper<SysUser> wrapper=new LambdaUpdateWrapper();
		wrapper.set(SysUser::getDelFlag,CommonConstants.ONE).in(SysUser::getUserId,dto.getIds());
		int update = sysUserMapper.update(null, wrapper);
		return update>CommonConstants.ZERO;
	}



    /**
	 * 通过查用户的全部信息
	 * @param sysUser 用户
	 * @return
	 */
	@Override
	public UserInfo findUserInfo(SysUser sysUser) {
		UserInfo userInfo = new UserInfo();
		userInfo.setSysUser(sysUser);
		// 设置角色列表 （ID）
//		List<Integer> roleIds = sysRoleService.findRolesByUserId(sysUser.getUserId()).stream().map(SysRole::getRoleId)
//				.collect(Collectors.toList());
		List<Long> roleIds = sysRoleMapper.getRoleIdsByUserId(sysUser.getUserId());
		// 设置权限列表（menu.permission）
//		Set<String> permissions = new HashSet<>();
//		roleIds.forEach(roleId -> {
//			List<String> permissionList = sysMenuService.findMenuByRoleId(roleId).stream()
//					.filter(menuVo -> StringUtils.isNotEmpty(menuVo.getPermission())).map(MenuVO::getPermission)
//					.collect(Collectors.toList());
//			permissions.addAll(permissionList);
//		});
		if(CollectionUtil.isNotEmpty(roleIds)){
			userInfo.setRoles(ArrayUtil.toArray(roleIds, Long.class));
//			List<String> permissionList =sysMenuMapper.getButtonList(roleIds);
//			if(CollectionUtil.isNotEmpty(permissionList)){
//				userInfo.setPermissions(ArrayUtil.toArray(permissionList, String.class));
//			}
			userInfo.setDataScopes(sysUserRoleScopeService.getPermissionList(sysUser.getUserId(),sysUser.getTenantId(),roleIds));
		}
		return userInfo;
	}

	@Override
	public List<String> getPermissionList() {
		List<Long> roleIds = sysRoleMapper.getRoleIdsByUserId(SecurityUtils.getUser().getId());
		if(CollectionUtil.isNotEmpty(roleIds)){
			return sysMenuMapper.getButtonList(roleIds);
		}
		return null;
	}


	@Override
	public Boolean lockUserStatus(UserLockDTO dto) {
		LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<>();
		wrapper.eq(SysUser::getPhone, dto.getUsername()).eq(SysUser::getDelFlag,CommonConstants.ZERO)
				.set(SysUser::getNormalFlag, dto.getNormalFlag());
		return update(null, wrapper);
	}

	@Override
	public UserDetailVO getUserDetailScope(Long userId) {
		SysUser sysUser=sysUserMapper.selectById(userId);
		UserDetailVO vo=BeanUtil.toBean(sysUser,UserDetailVO.class);
		//查询用户已分配的角色
		List<SysUserRole> roleList=sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId,userId));
		if(CollectionUtil.isNotEmpty(roleList)){
			List<RoleIdListVO> list=new ArrayList<>();
			List<UserRoleScopesVO> roleScopeList=new ArrayList<>();
			roleList.forEach(item ->{
				SysRole sysRole=sysRoleMapper.selectOne(Wrappers.<SysRole>lambdaQuery()
						.eq(SysRole::getDelFlag,CommonConstants.NOT_DEL).eq(SysRole::getRoleId,item.getRoleId()));
				if(ObjectUtil.isNotNull(sysRole)){
					RoleIdListVO vo1=new RoleIdListVO();
					vo1.setId(sysRole.getRoleId());
					vo1.setRoleName(sysRole.getRoleName());
					list.add(vo1);
					UserRoleScopesVO userRoleScopesVO=new UserRoleScopesVO();
					userRoleScopesVO.setRoleId(sysRole.getRoleId());
					userRoleScopesVO.setRoleName(sysRole.getRoleName());
					List<SysUserRoleScope> list1 = sysUserRoleScopeService.list(Wrappers.<SysUserRoleScope>lambdaQuery()
						.eq(SysUserRoleScope::getUserId,userId).eq(SysUserRoleScope::getRoleId,sysRole.getRoleId()));
					if(CollectionUtil.isNotEmpty(list1)){
						List<UserRoleScopeVO> userRoleScopeVOS=new ArrayList<>();
						for (SysUserRoleScope scope:list1) {
							UserRoleScopeVO userRoleScopeVO=new UserRoleScopeVO();
							userRoleScopeVO.setScopeId(scope.getScopeId());
							userRoleScopeVO.setScopeName(ScopeEnum.get(scope.getScopeId()).getDescription());
							context.getScopeStrategy(scope.getScopeId()).getAllList(userRoleScopeVO,scope,sysUser.getTenantId());
							userRoleScopeVOS.add(userRoleScopeVO);
						}
						userRoleScopesVO.setList(userRoleScopeVOS);
					}
					roleScopeList.add(userRoleScopesVO);
				}
			});
			vo.setRoleScopeList(roleScopeList);
			vo.setRoleList(list);
		}
		return vo;
	}

	@Override
	public Boolean checkUserPermission(String menuCode,Long scopeId, String name) {
		SysMenu sysMenu=sysMenuService.getOne(Wrappers.<SysMenu>lambdaQuery().eq(SysMenu::getPermission, menuCode));
		if(ObjectUtil.isNull(sysMenu)){
			return Boolean.FALSE;
		}
		DaoismUser user = SecurityUtils.getUser();
		for (Long v:SecurityUtils.getRoles()) {
			SysRoleMenu sysRoleMenu=sysRoleMenuService.getOne(Wrappers.<SysRoleMenu>lambdaQuery()
				.eq(SysRoleMenu::getRoleId,v).eq(SysRoleMenu::getMenuId,sysMenu.getMenuId()));
			if(ObjectUtil.isNotNull(sysRoleMenu)){
				SysUserRoleScope one = sysUserRoleScopeService.getOne(Wrappers.<SysUserRoleScope>lambdaQuery()
					.eq(SysUserRoleScope::getRoleId,v).eq(SysUserRoleScope::getUserId,user.getId())
					.eq(SysUserRoleScope::getScopeId,scopeId));
				if(ObjectUtil.isNotNull(one)){
					if(CommonConstants.ONE.equals(one.getAllFlag())){
						return Boolean.TRUE;
					}
					if(context.getScopeStrategy(scopeId).checkPermission(one,name,user.getTenantId())){
						return Boolean.TRUE;
					}
				}
			}
		}
		return Boolean.FALSE;
	}

    @Override
    public Boolean addScopeData(ScopoDataDTO dto) {
		DaoismUser user = SecurityUtils.getUser();
		List<Long> roles = SecurityUtils.getRoles();
		SysMenu sysMenu=sysMenuMapper.selectOne(Wrappers.<SysMenu>lambdaQuery().eq(SysMenu::getPermission,ScopeMenuEnum.get(dto.getType()).getMenuCode()));
		roles.forEach(item ->{
			SysRoleMenu sysRoleMenu=sysRoleMenuService.getOne(Wrappers.<SysRoleMenu>lambdaQuery()
				.eq(SysRoleMenu::getRoleId,item).eq(SysRoleMenu::getMenuId,sysMenu.getMenuId()));
			if(ObjectUtil.isNotNull(sysRoleMenu)){
				SysUserRoleScope scope = sysUserRoleScopeService.getOne(Wrappers.<SysUserRoleScope>lambdaQuery()
					.eq(SysUserRoleScope::getRoleId,item).eq(SysUserRoleScope::getUserId,user.getId())
					.eq(SysUserRoleScope::getScopeId, dto.getType()));
				if(CommonConstants.ZERO.equals(scope.getAllFlag()) ){
					if(StrUtil.isNotBlank(scope.getIds())){
						scope.setIds(scope.getIds()+","+CollectionUtil.join(dto.getIds(),","));
					}else {
						scope.setIds(CollectionUtil.join(dto.getIds(),","));
					}
					if(!sysUserRoleScopeService.updateById(scope)){
						throw new BizException(ResultCodeEnum.SAVE_COMPANY_FAIL);
					}
				}
			}
		});
        return null;
    }

}
